/*
 * Hidden Equity LLC
 * Author: Maksym Fedyay, Kyiv, mcsimf@gmail.com
 * Date: 29.02.2012
 */

package com.hiddenequity.acts;

import java.util.ArrayList;
import java.util.Map;

import com.hiddenequity.report_definition_service.PredicateOperator;
import com.hiddenequity.report_definition_service.ReportDefinitionResponseParser;
import com.hiddenequity.report_definition_service.ReportDefinitionService;
import com.hiddenequity.report_definition_service.ReportField;
import com.hiddenequity.report_definition_service.ReportType;
import com.hiddenequity.utils.AuthService;
import com.hiddenequity.utils.City;
import com.hiddenequity.utils.Communication;
import com.hiddenequity.utils.Country;
import com.hiddenequity.utils.DateProcessor;
import com.hiddenequity.utils.LocationDataProvider;
import com.hiddenequity.utils.Province;
import com.hiddenequity.utils.UrlBuncher;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class Act_GeoReport extends Act_Super{

	private String countryName;
	private String regionName;
	private String cityName;
	private String countryCode;
	private String regionCode;

	private ListView reportList;
	private TextView header_geo_report;
	private LinearLayout ll_header_geo_report;
	
	
	private final int LEVEL_COUNTRY = 0;
	private final int LEVEL_REGION = 1;
	private final int LEVEL_CITY = 2;
	private final int LEVEL_DATA = 3;
	
	private int reportLevel;
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}


	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_geo_report);

		Intent intent = getIntent();
		dateRangeItem = intent.getIntExtra("dateRangeItem", 0);

		title.setText(R.string.title_geo_report);
		sub_title.setVisibility(View.GONE);
		filter.setVisibility(View.GONE);
		
		header_geo_report = (TextView) findViewById(R.id.header_geo_report);
		ll_header_geo_report = (LinearLayout) findViewById(R.id.ll_header_geo_report);
		ll_header_geo_report.setVisibility(View.GONE);
		
		reportLevel = LEVEL_COUNTRY;
		

		reportList = (ListView) findViewById(R.id.list_geo_report);
		reportList.setAdapter(reportAdapter);
		reportList.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
				Map<String, String> itemMap = (Map<String, String>) reportList.getItemAtPosition(position);		

				switch (reportLevel) {
					case LEVEL_COUNTRY: 
						countryName = itemMap.get("Country/Territory");
						if(!countryName.contains("All other")){
							clearList();
							setReportByGeoItem();
							runOperationAsync(OPERATION_GET_DATA, getString(R.string.progress_loading), false);
						} else {
							return;
						}
						break;
					case LEVEL_REGION: 
						regionName = itemMap.get("Region");
						if(!regionName.contains("All other")){
							clearList();
							setReportByGeoItem();
							runOperationAsync(OPERATION_GET_DATA, getString(R.string.progress_loading), false);
						} else {
							return;
						}
						break;
					case LEVEL_CITY: 
						cityName = itemMap.get("City");
						
						if(!cityName.contains("All other")){
							clearList();
							setReportByGeoItem();
							runOperationAsync(OPERATION_GET_DATA, getString(R.string.progress_loading), false);
						} else {
							return;
						}
						break;
				}	
				
				

				
				
			}
		});
			
		runOperationAsync(OPERATION_GET_DATA, getString(R.string.progress_loading), false);
		
	}
	
	
	
	/*
	 * Set report level by Geo item
	 */
	private void setReportByGeoItem(){
		String headerText = "";
		
		if(countryName != null){
			headerText += countryName;
			reportLevel = LEVEL_REGION;
		}
		if(regionName != null){
			headerText += " > " + regionName;
			reportLevel = LEVEL_CITY;
		}
		if(cityName != null){
			headerText += " > " + cityName;
			reportLevel = LEVEL_DATA;
		}		
		
		if(reportLevel == LEVEL_COUNTRY){
			ll_header_geo_report.setVisibility(View.GONE);
		}else {
			ll_header_geo_report.setVisibility(View.VISIBLE);
			header_geo_report.setText(headerText);
		}
	}//setReportByGeoItem
	
	
	/*
	 * Clear list
	 */
	private void clearList(){
		columns.clear();
		rows.clear();
		reportAdapter.notifyDataSetChanged();
	}//clearList
	
	
	
	/*
	 * (non-Javadoc)
	 * @see android.app.Activity#onBackPressed()
	 */
	@Override
	public void onBackPressed(){
		clearList();

		reportLevel -= 1;
		if(reportLevel == -1){
			super.onBackPressed();
			return;
		}
		if(reportLevel == LEVEL_CITY){
			cityName = null;
		}
		if(reportLevel == LEVEL_REGION){
			regionName = null;
			cityName = null;
			regionCode =null;
		}	
		if(reportLevel == LEVEL_COUNTRY){
			countryName = null;
			regionName = null;
			cityName = null;
			countryCode = null;
			regionCode =null;
		}			
		
		setReportByGeoItem();
		
		runOperationAsync(OPERATION_GET_DATA, getString(R.string.progress_loading), false);
	}//onBackPressed
	
	
	/*
	 * Handles requested activity result
	 */
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if(resultCode == RESPONSE_FINISH_REQUIRED){
			finishActivityWithResult(RESPONSE_FINISH_REQUIRED);
		} else if(resultCode == RESPONSE_GOTO_MAIN_ACTIVITY){
			finishActivityWithResult(RESPONSE_GOTO_MAIN_ACTIVITY);
		} else if(requestCode == REQUEST_REFRESH_REQUIRED && resultCode == RESPONSE_REFRESH_REQUIRED){
			runOperationAsync(OPERATION_GET_DATA, getString(R.string.progress_refreshing), false); 			
		}
    	
	}// onActivityResult
	
	
	ArrayList<Map<String, String>> columns = new ArrayList<Map<String,String>>();
	static ArrayList<Map<String, String>> rows = new ArrayList<Map<String,String>>();

	
	
	/*
	 * get report
	 */
	private void getGeoReport(){
		switch (reportLevel) {
			case LEVEL_COUNTRY: 
				countryLevelReport();
				break;
			case LEVEL_REGION: 
				regionLevelReport();
				break;
			case LEVEL_CITY: 
				cityLevelReport();
				break;
			case LEVEL_DATA: 
				dataLevelReport();
				break;
		}
	}//getGeoReport
	
	
	
	/*
	 * Get geo report Country level
	 */
	private void countryLevelReport(){
		String[] fields = new String[] {
			ReportField.COUNTRY_CRITERIA_ID,
			ReportField.CLICKS
		};
		
		String reportDefinition = ReportDefinitionService.defineReport(
				ReportType.GEO_PERFORMANCE_REPORT, fields, dateRangeItem, null);
		
		String report = Communication.requestAdHogRequest(UrlBuncher.URL_ADHOC_REPORT, reportDefinition);
		ReportDefinitionResponseParser parser = new ReportDefinitionResponseParser(report);
		columns = parser.getReportColumns();
		rows = parser.getReportRows(columns);
	}//getGeoReportCountryLevel

	
	
	/*
	 * Get geo report region level
	 */

	private void regionLevelReport(){

		String[] fields = new String[] {
			ReportField.REGION_CRITERIA_ID,
			ReportField.CLICKS
		};
		
		Country country = LocationDataProvider.getCountryByName(countryName);
		countryCode = country.getCode();
		
		String[] predicateValue = new String[]{
				country.getCriteriaId()
		};
		
		String[] predicates = new String[]{
				ReportDefinitionService.setPredicator(ReportField.COUNTRY_CRITERIA_ID, 
						PredicateOperator.EQUALS, predicateValue)				
		};

		String reportDefinition = ReportDefinitionService.defineReport(
				ReportType.GEO_PERFORMANCE_REPORT, fields, dateRangeItem, predicates);
		String report = Communication.requestAdHogRequest(UrlBuncher.URL_ADHOC_REPORT, reportDefinition);
		ReportDefinitionResponseParser parser = new ReportDefinitionResponseParser(report);
		columns = parser.getReportColumns();
		rows = parser.getReportRows(columns);
	}//getGeoReportRegionLevel
	
	
	/*
	 * Get geo report city level
	 */
	
	private void cityLevelReport(){

		String[] fields = new String[] {
			ReportField.CITY_CRITERIA_ID,
			ReportField.CLICKS
		};
		
		Province province = LocationDataProvider.getProvinceByName(regionName, countryCode);
		regionCode = province.getProvinceCode();
		
		String[] predicateRegion = new String[]{
				province.getCriteriaId()
		};
		
		String[] predicates = new String[]{
				ReportDefinitionService.setPredicator(ReportField.REGION_CRITERIA_ID, 
						PredicateOperator.EQUALS, predicateRegion)						
		};

		String reportDefinition = ReportDefinitionService.defineReport(
				ReportType.GEO_PERFORMANCE_REPORT, fields, dateRangeItem, predicates);
		String report = Communication.requestAdHogRequest(UrlBuncher.URL_ADHOC_REPORT, reportDefinition);
		ReportDefinitionResponseParser parser = new ReportDefinitionResponseParser(report);
		columns = parser.getReportColumns();
		rows = parser.getReportRows(columns);
	}//getGeoReportCityLevel
	
	
	
	
	/*
	 * Get geo report city level
	 */
	
	private void dataLevelReport(){

		String[] fields = new String[] {
			ReportField.CAMPAIGN_NAME,
			ReportField.CLICKS,
			ReportField.COST,
			ReportField.IMPRESSION
		};
		
		City city = LocationDataProvider.getCityByName(cityName, regionCode, countryCode);
		
		String[] predicateCity = new String[]{
				city.getCriteriaId()
		};
		
		String[] predicates = new String[]{
				ReportDefinitionService.setPredicator(ReportField.CITY_CRITERIA_ID, 
						PredicateOperator.EQUALS, predicateCity),						
		};

		String reportDefinition = ReportDefinitionService.defineReport(
				ReportType.GEO_PERFORMANCE_REPORT, fields, dateRangeItem, predicates);
		String report = Communication.requestAdHogRequest(UrlBuncher.URL_ADHOC_REPORT, reportDefinition);
		ReportDefinitionResponseParser parser = new ReportDefinitionResponseParser(report);
		columns = parser.getReportColumns();
		rows = parser.getReportRows(columns);
	}//getGeoReportCityLevel

	
	
	/*
     * Base adapter for listview
     */
	private BaseAdapter reportAdapter = new BaseAdapter() {

		public int getCount() {
			int size = Act_GeoReport.rows.size();
			return size;
		}

		public Object getItem(int position) {
			return Act_GeoReport.rows.get(position);
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			View row = convertView;
			
			if(columns.size() <= 2){
				if (row == null) {
					LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
					row = mInflater.inflate(R.layout.list_row_geo_report, null);
				}

				TextView geo_report_level_item = (TextView) row.findViewById(R.id.geo_report_level_item);
				TextView geo_report_item_clicks = (TextView) row.findViewById(R.id.geo_report_item_clicks);
				
	    		for(Map<String, String> column : columns){
	    			for(Map.Entry<String, String> single_column : column.entrySet()){
	    				
	    				String field = single_column.getValue();
	    				String value = Act_GeoReport.rows.get(position).get(field);
	    				
	    				if(columns.indexOf(column) == 0){
	    					geo_report_level_item.setText(value);
	    					continue;
	    				}
	    				
	    				if(columns.indexOf(column) > 0 ){
	    					geo_report_item_clicks.setText(value);
	    					continue;
	    				}
	    			}
	    		}
				
				
			} else {
				if (row == null) {
					LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
					row = mInflater.inflate(R.layout.report_row, null);
				}

				LinearLayout report_row = (LinearLayout) row.findViewById(R.id.report_row);
				report_row.removeAllViews();
				TextView report_headline = (TextView) row.findViewById(R.id.report_headline);
				
				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				
				ImageView report_expand_sign = (ImageView) row.findViewById(R.id.report_expand_sign);
	        	
	            report_expand_sign.setVisibility(View.GONE);	
				
	    		for(Map<String, String> column : columns){
	    			for(Map.Entry<String, String> single_column : column.entrySet()){
	    				
	    				String field = single_column.getValue();
	    				String value = Act_GeoReport.rows.get(position).get(field);
	    				
	    				if(columns.indexOf(column) == 0){
	    					report_headline.setText(value);
	    					continue;
	    				}
	    				
		    			View report_field = inflater.inflate(R.layout.report_field, null, false);
		            	TextView field_name = (TextView) report_field.findViewById(R.id.field_name);
		            	TextView field_value = (TextView) report_field.findViewById(R.id.field_value);

		            	field_name.setText(field);
		            	field_value.setText(value);

		            	report_row.addView(report_field);
	    			}
	    		}
				
			}

			return row;
		}
	};//campaignListAdapter
	
	
	
	
	
	
	/*
	 * Async operation
	 */
	private void runOperationAsync(final int operation, String message, boolean overlap) {

		//Stop if thread is alive
		if(thread.isAlive() && !overlap)
			return;
		
		//Show progress dialog
		final ProgressDialog progressDialog = ProgressDialog.show(this, "",
				message, true);

		//Check if Internet connection alive
		if(!isConnectionAvalable()){
			progressDialog.dismiss();
			return;
		}

		thread = new Thread(){
			public void run() {
				//Perform authentication
				new AuthService(Act_GeoReport.this, getApplication());
				//Perform operation
				if (AuthService.authToken != null) {
					try {
						switch (operation) {
						case OPERATION_GET_DATA:
							LocationDataProvider.getProvinceList(getApplication());
							LocationDataProvider.getCountryList(getApplication());
							LocationDataProvider.getCityList(getApplication());
							Act_GeoReport.this.getGeoReport();
							break;	
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				//Perform postoperation
				Act_GeoReport.this.runOnUiThread(new Runnable() {
					public void run() {
						
						progressDialog.dismiss();

						if (AuthService.authToken != null) {
							
							showOperationError(R.string.msg_title_error, responseErrorString);

							switch (operation) {
							case OPERATION_GET_DATA:
									reportAdapter.notifyDataSetChanged();
									break;
							}
						} else {
							Intent intent = new Intent(Act_GeoReport.this.getApplicationContext(),
									Act_Login.class);
							startActivityForResult(intent, REQUEST_REFRESH_REQUIRED);
						}
					}
				});
			}
		};
		thread.start(); 		
			
	}//runOperationAsync
	
	
	
}
